package com.mh.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Date:2025/2/10
 * author:zmh
 * description: 通用接口
 **/

@RestController
@RequestMapping("/commons")
@Slf4j
@CrossOrigin
public class CommonController {

    @Value("${FILEPATH}")
    private String picturePath;

    @Value("${MY_ENV}")
    private String myEnv;

    /**
     * 获取图片（文件下载接口）
     * @return 返回字节数据流
     * @throws  ·
     */
    @GetMapping("/download")
    public ResponseEntity<Resource> getImage(String picName) {
        // 处理目录路径拼接问题（/符号会被特殊转义，所以前端使用$符号代替，再这替换回/）
        picName = picName.replace("$", "/");
        String randomPic = picturePath + picName;
        log.info("获取图片路径==>{}", randomPic);

        File file = new File(randomPic);

        if(!file.exists()){
            log.info("文件没有找到...");
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);  // 设置响应类型二进制流类型

        // 添加Content-Disposition头信息
        String fileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8).replace("+", "%20");
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");

        Resource resource = new FileSystemResource(file);
        try{
            headers.setContentLength(resource.contentLength());  // 设置响应内容得长度
        }catch(IOException e){
            return new ResponseEntity<>(headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        return new ResponseEntity<>(resource, headers, HttpStatus.OK);
    }

    /**
     * 文件上传接口
     * @param file 前端传入的文件对象
     * @return 返回存在服务器的文件名称
     */
    @PostMapping("/upload")
    public ResponseEntity<Map<String, Object>> fileUpload(@RequestParam("file") MultipartFile file) {
        Map<String, Object> response = new HashMap<>();
        // 获取上传的图片文件后缀名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));
        // 检查文件是否为空
        if (file.isEmpty()) {
            response.put("errno", 1);
            response.put("message", "File is empty!");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
        }
        // 检查文件名是否合法,避免目录遍历攻击
        String fileName = StringUtils.cleanPath(originalFilename);
        if (fileName.contains("..")) {
            response.put("errno", 1);
            response.put("message", "Illegal name!");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
        }
        try {
            // 给上传的图片随机生成一个名称，将之返回，
            // 用户就可以根据此名称下载图片，防止图片名称冲突。
            UUID uuid = UUID.randomUUID();
            String randomUUIDString = uuid.toString();
            // 将文件保存到指定目录文件
            File targetFile = new File(this.picturePath + randomUUIDString + fileExtension);
            // 将传入的图片转存到指定目录文件
            file.transferTo(targetFile);
            // 构建成功响应
            Map<String, Object> data = new HashMap<>();
            String imageUrl = myEnv +"/commons/download?picName=" + randomUUIDString + fileExtension;
            data.put("url", imageUrl); // 使用拼接的URL路径
            data.put("alt", "Image description"); // 可以根据需要从文件或其他地方获取
            data.put("href", imageUrl); // 使用同一个URL作为href
            data.put("pictureName", randomUUIDString + fileExtension);
            response.put("errno", 0);
            response.put("data", data);
            return ResponseEntity.ok(response);
        } catch (IOException e) {
            e.printStackTrace();
            response.put("errno", 1);
            response.put("message", "Server error!");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    /**
     * 删除文件图片
     * @param imageName 图片名称
     * @return ·
     */
    @DeleteMapping("/deleteFile/{imageName}")
    public String deleteImage(@PathVariable("imageName") String imageName) {
        if (StringUtils.isEmpty(imageName)) {
            return "请传入图片名称";
        }

        String imagePath = this.picturePath + imageName;

        try {
            File file = new File(imagePath);

            if (!file.exists()) {
                return "图片没有找到!";
            }

            if (!file.delete()) {
                return "删除图片失败!";
            }

            return "删除图片成功!";

        } catch (Exception e) {
            return "发生错误!";
        }
    }
}
